//
// Copyright (c) 2002-2010 "Neo Technology,"
//     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// This file is part of Neo4j.
// 
// Neo4j is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.graphdb
{
    /// <summary>
    /// A client hook for evaluating whether the traverser should traverse beyond a
    /// specific node. This is used for pruning the traversal.
    /// When a traverser is created, the client parameterizes it with a
    /// StopEvaluator. The traverser then invokes the {@link #IsStopNode
    /// IsStopNode()} operation just before traversing the relationships of a node,
    /// allowing the client to either approve or disapprove of traversing beyond that
    /// node.
    /// When implementing a StopEvaluator, the client investigates the information
    /// encapsulated in a <seealso cref="TraversalPosition"/> to decide whether to block
    /// traversal beyond a node or not. For example, here's a snippet detailing a
    /// StopEvaluator that blocks traversal beyond a node if it has a certain
    /// property value:
    /// 
    /// <pre>
    /// <code>
    /// StopEvaluator stopEvaluator = new StopEvaluator()
    /// {
    ///     // Block traversal if the node has a property with key 'key' and value
    ///     // 'someValue'
    ///     public boolean <seealso cref="IsStopNode(TraversalPosition)"></seealso>
    ///     ( <seealso cref="TraversalPosition"/> position )
    ///     {
    ///         if ( position.<seealso cref="TraversalPosition#isStartNode() isStartNode"/>() )
    ///         {
    ///             return false;
    ///         }
    ///         <seealso cref="Node"/> node = position.<seealso cref="TraversalPosition#currentNode() currentNode"/>();
    ///         Object someProp = node.<seealso cref="Node#getProperty(String, Object) getProperty"/>( "key", null );
    ///         return someProp instanceof String &&
    ///             ((String) someProp).equals( "someValue" );
    ///     }
    /// };
    /// </code>
    /// </pre> 
    /// </summary>
    public class StopEvaluator
    {
        #region Delegates

        /// <summary>  
        /// Method invoked by traverser to see if current position is a stop node.
        /// </summary>
        /// <param name="currentPosition"> the traversal position </param>
        /// <returns>
        /// True if current position is a stop node 
        /// </returns>
        public delegate bool IsStopNode(TraversalPosition currentPosition);

        #endregion

        #region Implementations

        ///  <summary> 
        ///  Traverse until the end of the graph. This evaluator returns
        ///   <code>false</code> all the time. 
        ///  </summary>
        IsStopNode END_OF_GRAPH = delegate {
                                          return false;
                                      };
        ///  <summary>  
        /// Traverses to depth 1.
        /// </summary>
        IsStopNode DEPTH_ONE = delegate(TraversalPosition currentPosition)
                                   {
                                       return currentPosition.Depth() >= 1;
                                   };

        #endregion
    }
}